package com.erp.common.utils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolUtils {
    /**
     * 核心线程数
     */
    private int corePoolSize = 5;

    /**
     * 最大线程数
     * [最大线程数 不能小于 核心线程数]
     */
    private int maximumPoolSize = Math.max(Runtime.getRuntime().availableProcessors() * 2, corePoolSize);

    /**
     * 存活时间
     */
    private int keepAliveTime = 3;

    /**
     * 有界队列
     */
    private BlockingQueue blockingQueue = new ArrayBlockingQueue<Runnable>(10);


    private static ThreadPoolUtils instance = null;


    private ThreadPoolUtils() {
    }

    public static ThreadPoolUtils getInstance() {
        /**
         * 双重检测机制
         */
        if (instance == null) {
            synchronized (ThreadPoolUtils.class) {
                if (instance == null) {
                    instance = new ThreadPoolUtils();
                }
            }
        }
        return instance;
    }


    public ThreadPoolExecutor createThreadPoolExecutor() {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
                TimeUnit.SECONDS, blockingQueue,
                new ThreadPoolExecutor.DiscardOldestPolicy());
        return threadPool;
    }

    public ThreadPoolExecutor createThreadPoolExecutor(ThreadFactory threadFactory) {

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, blockingQueue,
                threadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());

        return threadPool;
    }

    public ThreadPoolExecutor createThreadPoolExecutor(ThreadFactory threadFactory, RejectedExecutionHandler handler) {

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, blockingQueue,
                threadFactory, handler);

        return threadPool;
    }
}
